package net

import (
	parent "crypto/tls"
	"crypto/x509"
	"google.golang.org/grpc/credentials"
	"os"
)

func NewTls(rootCaFile, certFile, keyFile string) *tls {
	return &tls{
		rootCaFile: rootCaFile,
		certFile:   certFile,
		keyFile:    keyFile,
	}
}

type tls struct {
	rootCaFile string
	certFile   string
	keyFile    string
}

func (r *tls) pool() *x509.CertPool {
	ca, err := os.ReadFile(r.rootCaFile)
	if err != nil {
		panic(err)
	}

	pool := x509.NewCertPool()
	ok := pool.AppendCertsFromPEM(ca)
	if !ok {
		panic("append root ca not ok")
	}

	return pool
}
func (r *tls) pair() parent.Certificate {
	pair, err := parent.LoadX509KeyPair(r.certFile, r.keyFile)
	if err != nil {
		panic(err)
	}

	return pair
}
func (r *tls) Server() credentials.TransportCredentials {
	return credentials.NewTLS(&parent.Config{
		ClientAuth:   parent.RequireAndVerifyClientCert,
		ClientCAs:    r.pool(),
		Certificates: []parent.Certificate{r.pair()},
	})
}
func (r *tls) Client() credentials.TransportCredentials {
	return credentials.NewTLS(&parent.Config{
		ServerName:   "localhost",
		RootCAs:      r.pool(),
		Certificates: []parent.Certificate{r.pair()},
	})
}
